﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using MicroTest_Client;
using MicroTest.Properties;

namespace MicroTest
{
    public partial class FrmExam : Form
    {
        /// <summary>
        /// 此变量无用
        /// </summary>
        private FrmDetails frmDetails;
        /// <summary>
        /// 主界面是的书写小窗口集合，以点阵笔序列号为键值
        /// </summary>
        private Dictionary<string, DrawingWindow> statusWindows;
        /// <summary>
        /// 笔列表字典集合
        /// </summary>
        private Dictionary<string, PenItem> penItemList;
        /// <summary>
        /// 点阵笔总数，已连接的点阵笔数，断开连接的点阵笔数
        /// </summary>
        private int All=0, Conn=0, Disconn=0;
        private int tickCount = 0;
        /// <summary>
        /// 考试开始时间
        /// </summary>
        private DateTime testStart;
        
        ///// <summary>
        ///// 考试是否结束
        ///// </summary>
        private bool IsStoped = false;
        /// <summary>
        /// 后台线程
        /// </summary>
        private BackgroundWorker backgroundWorker;
        /// <summary>
        /// 是否正在导出数据 
        /// </summary>
        public bool IsExporting = false;
        /// <summary>
        /// 导出数据是否成功
        /// </summary>
        private bool ExportSuccess = false;
        /// <summary>
        /// 上传是否成功
        /// </summary>
        private bool UploadSuccess = false;
        private string UploadMsg = string.Empty;
        /// <summary>
        /// 笔落笔抬笔状态
        /// </summary>
        private Dictionary<string, bool> PenDownStatus;
       // private bool IsPenDown = false;
        /// <summary>
        /// 笔序列号与学生姓名的对应的字典
        /// </summary>
        private Dictionary<string, string> studentListDic;
        /// <summary>
        /// 异步数据存储类
        /// </summary>
        private SaveStrokeAsync saveStrokeAsync;
        //private FrmZoom frmZoom;
        //private Image BackgroundImage = null;
        /// <summary>
        /// 当前选中的左侧列表项
        /// </summary>
        private PenItem currentPenItem = null;
        private int windowWidth = 0;
        private int windowHeight = 0;
        /// <summary>
        /// 缩放尺寸
        /// </summary>
        private List<ZoomSize> zoomValues = new List<ZoomSize>();
        /// <summary>
        /// 考试状态
        /// </summary>
        private ExamStatus examStatus = ExamStatus.Exam_Stoped;
        private const int minDrawingWidth = 210;
        private const int minDrawingHeight = 297;
        private const int drawingWindowNameHeight = 35;

        /// <summary>
        /// 是否显示背景
        /// </summary>
        private bool ShowBackground = true;
        /// <summary>
        /// 异常恢复模式
        /// </summary>
        public bool ResumeMode = false;
        public FrmExam()
        {
            InitializeComponent();
            frmDetails = new FrmDetails();
            statusWindows = new Dictionary<string, DrawingWindow>();
            penItemList = new Dictionary<string, PenItem>();
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += BackgroundWorker_DoWork;
            this.WindowState = FormWindowState.Maximized;
            studentListDic = new Dictionary<string, string>();
            PenDownStatus = new Dictionary<string, bool>();

        }

        /// <summary>
        /// 考试初始化操作
        /// </summary>
        public void IniExam()
        {
            flpClient.GetType().GetProperty("DoubleBuffered",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(flpClient, true, null);

            InitControl();
            ExportSuccess = false;
            UploadSuccess = false;
            currentPenItem = null;
            tickCount = 0;
            windowWidth = 0;
            windowHeight = 0;
            ShowBackground = true;
            examStatus = ExamStatus.Exam_Sign;
            btnBackground.NormalImage = Resources.oper_btn_hidebg;
            btnBackground.HoverImage = Resources.oper_btn_hidebg_hover;
            btnBackground.DownImage = Resources.oper_btn_hidebg_active;
            btnBackground.DisableImage = Resources.oper_btn_hidebg_disabled;
            //回复异常
            //ResumeMode = ResumeData();
            //学生名单
            Program.MTInfo.ClearStudentCard();
            List<StudentCard> cardList = Program.StudentInfo.GetCardList();
            foreach (var item in cardList)
            {
                Program.MTInfo.AddStudentCard(item);
            }
            //清空小窗
            statusWindows.Clear();
            flpClient.Controls.Clear();

            Conn = 0;
            All = Program.StudentInfo.BandList.Count;
            Disconn = All;
            UpdateCountStatus();
            penItemList.Clear();
            flpPenlist.Controls.Clear();

            studentListDic.Clear();
            AddPenList();

            examStatus = ExamStatus.Exam_Sign;
            if(ResumeMode)
            {
                labKS.Text ="【"+ Program.MTInfo.MicroTestTitle+"】";
                labKS.Top = labBJ.Top;
                labKS.Left = labBJ.Right;
                if(labKS.Right>pnlStartInfo.Left)
                {
                    labKS.Width = pnlStartInfo.Left - labKS.Left - 20;
                }

                LoadDrawingWindws();
                examStatus = ExamStatus.Exam_LoadedPaper;
                btnKs_Click(null, null);
            }


            
        }
        /// <summary>
        /// 把签到名单中的笔添加到笔列表
        /// </summary>
        private void AddPenList()
        {
            foreach (var item in Program.StudentInfo.BandList)
            {
                PenItem pi = new PenItem();
                pi.PenSerial = item.PenSerial;
                pi.NormalImage = Resources.pen_ico_link;
                pi.DisableImage = Resources.pen_ico_fail;
                pi.DisconectedImage = Resources.pen_ico_fail;
                pi.SetName(item.Name);
                pi.SelectedColor = Color.FromArgb(226, 175, 134);
                pi.ChangePenStatus(PenStatus.Disabled);
                pi.ClickPen += Pi_ClickPen;
                studentListDic.Add(item.PenSerial, item.Name);
                penItemList.Add(item.PenSerial, pi);
                flpPenlist.Controls.Add(pi);
            }
        }
        /// <summary>
        /// 用旧笔替换新笔
        /// </summary>
        /// <param name="penserial"></param>
        private string ReplacePenItem(string penserial)
        {
            
            PenItem pi = null;
            string oldPenSerial = string.Empty;
            string studentName = studentListDic[penserial];
            foreach (var item in studentListDic)
            {
                if(studentName.Equals(item.Value)&&!penserial.Equals(item.Key))
                {
                    oldPenSerial = item.Key;
                    break;

                }
            }
            foreach (var item in penItemList)
            {
                if(oldPenSerial.Equals(item.Value.PenSerial))
                {
                    pi = item.Value;
                    //oldPenSerial = item.Key;
                    break;
                }
            }
            if(pi!=null)
            {
                //pi.PenSerial = penserial;
                this.Invoke(new Action(() => { pi.PenSerial = penserial;pi.SetName(studentName); }));
                if(penItemList.ContainsKey(oldPenSerial))
                    penItemList.Remove(oldPenSerial);
                if (penItemList.ContainsKey(penserial) == false)
                    penItemList.Add(penserial, pi);
            }
            return oldPenSerial;
        }

        /// <summary>
        /// 更新笔的签到状态
        /// </summary>
        /// <param name="penSerial"></param>
        /// <param name="ps"></param>
        private void UpdatePenSignInStatus(string penSerial,PenStatus ps)
        {
            if(this.InvokeRequired)
            {
                Action<string, PenStatus> ac = new Action<string, PenStatus>(UpdatePenSignInStatus);
                this.Invoke(ac, new object[] { penSerial, ps });
            }
            else
            {
                if (penItemList[penSerial].PenItemStatus != ps)
                {
                    penItemList[penSerial].ChangePenStatus(ps);
                    if(ps==PenStatus.Normal)
                    {
                        Conn++;
                        Disconn--;
                    }
                    else if(ps==PenStatus.DisConnected)
                    {
                        Conn--;
                        Disconn++;
                    }
                    UpdateCountStatus();
                }
            }
            
        }
        /// <summary>
        /// 载入所有人的书写小窗口
        /// </summary>
        private void LoadDrawingWindws()
        {           
            bool isA4Page = true;
            foreach (var stu in studentListDic)
            {
                string penSerial = stu.Key;
                DrawingWindow cs = new DrawingWindow(penSerial, Program.MTInfo.MicroTestPaperImage,ResumeMode);
                //cs.SuspendLayout();
                cs.SetName(stu.Value);
                statusWindows.Add(penSerial, cs);
                int width = flpClient.Width;
                if (windowHeight != 0)
                {
                    cs.Height = windowHeight;
                    cs.Width = windowWidth;
                    //cs.SetWindowsSize(windowWidth, windowHeight);
                }
                else
                {
                    if (Program.MTInfo.MicroTestPaperImage.Count != 0)
                    {
                        foreach (var item in Program.MTInfo.MicroTestPaperImage)
                        {
                            if (item.Value.Width < item.Value.Height)
                            {
                                windowWidth = minDrawingWidth;
                                windowHeight = minDrawingHeight + drawingWindowNameHeight;
                            }
                            else
                            {
                                isA4Page = false;
                                windowWidth = 2* minDrawingWidth;
                                windowHeight = minDrawingHeight + drawingWindowNameHeight;
                            }
                            break;
                        }
                        cs.Width = windowWidth;
                        cs.Height = windowHeight;
                        //cs.SetWindowsSize(windowWidth, windowHeight);

                    }
                }
                int w = cs.Width;
                int l = width % w / 2;
                cs.Margin = new Padding(20, 10, 20, 10);
                //cs.Visible = false;
                flpClient.Controls.Add(cs);
            }
            zoomValues.Clear();
            int smallWidth = minDrawingWidth;
            int smallHeight = minDrawingHeight;
            if (!isA4Page)
                smallWidth = 2 * minDrawingWidth;
            
            ZoomSize sz = new ZoomSize(smallWidth, smallHeight + drawingWindowNameHeight);
            zoomValues.Add(sz);

            int clientAreaHeight = flpClient.Height-10;
            int clientAreaWidth = flpClient.Width-20-20;

            int drawingWindowHeight = clientAreaHeight;
            int drawingWindowWidth = (int)(1.0 * (drawingWindowHeight - drawingWindowNameHeight) * smallWidth / smallHeight);
            sz = new ZoomSize(drawingWindowWidth, drawingWindowHeight);
            zoomValues.Add(sz);


            drawingWindowWidth = clientAreaWidth;
            drawingWindowHeight = (int)(1.0 * drawingWindowWidth / smallWidth * smallHeight) + drawingWindowNameHeight;
            sz = new ZoomSize(drawingWindowWidth, drawingWindowHeight);
            zoomValues.Add(sz);

            foreach (var item in flpClient.Controls)
            {
                (item as DrawingWindow).SetLabelVisable(true);
                //(item as DrawingWindow).Visible = true;

            }


        }
        /// <summary>
        /// 用新笔替换原有的笔
        /// </summary>
        /// <param name="penserial"></param>
        private string ReplaceDrawingWindow(string penserial)
        {
            DrawingWindow dw = null;
            string oldPenSerial = string.Empty;
            string studentName = studentListDic[penserial];
            foreach (var item in studentListDic)
            {
                if (studentName.Equals(item.Value) && !penserial.Equals(item.Key))
                {
                    oldPenSerial = item.Key;
                    break;
                }
            }
            foreach (var item in statusWindows)
            {
                if (oldPenSerial.Equals(item.Value.GetPenSerial()))
                {
                    dw = item.Value;
                    //oldPenSerial = item.Key;
                    break;
                }
            }
            if (dw != null)
            {
                this.Invoke(new Action(() => { dw.ReplacePenSerial(penserial); }));

                //dw.ReplacePenSerial( penserial);
                if (statusWindows.ContainsKey(oldPenSerial))
                    statusWindows.Remove(oldPenSerial);
                if (statusWindows.ContainsKey(penserial) == false)
                    statusWindows.Add(penserial, dw);
            }
            return oldPenSerial;
        }
        FrmPromot frm = new FrmPromot();
        private void ShowReplaceResult(string studentName,string oldPenserial,string newPenserial)
        {
            if(this.InvokeRequired)
            {
                Action<string, string, string> ac = new Action<string, string, string>(ShowReplaceResult);
                this.Invoke(ac, new object[] { studentName, oldPenserial, newPenserial });
            }
            else
            {
                frm.Show();
                frm.SetPromptString(string.Format("【{0}】的点阵笔已替换为【{1}】", studentName, newPenserial));
            }
        }
        void DeleteDirectory(string path)
        {
            DirectoryInfo dir = new DirectoryInfo(path);
            if (dir.Exists)
            {
                DirectoryInfo[] childs = dir.GetDirectories();
                foreach (DirectoryInfo child in childs)
                {
                    child.Delete(true);
                }
                dir.Delete(true);
            }
        }
        /// <summary>
        /// 打包并上传数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            
            saveStrokeAsync.StopSaving();
            //打压缩包
            //string zipFile = Application.StartupPath + "\\data\\" + Program.TEST_KEY + ".mt";
            //string zipFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\MicroTest\\" + Program.TEST_KEY + ".mt";
            string zipFile = Program.DATA_ROOT+"\\" + Program.MTInfo.MicroTestID + ".mt";

            //if (File.Exists(zipFile))
            //    File.Delete(zipFile);
            if (File.Exists(zipFile))
            {
                ExportSuccess = true;//已经打包
            }
            else
            { 
                try
                {
                    //specialfolder:folder=CommonApplicationData}/MicroTest/${shortdate}.log
                    DateTime dt = DateTime.Now;
                    string logFileName=dt.ToString("yyyy-MM-dd")+".log";
                    string LogFilePath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\WiseClass\\" + logFileName;
                    if(File.Exists(LogFilePath))
                    {
                        try
                        {
                            string destFileName = Program.DATA_FOLDER + "\\" + logFileName;
                            File.Copy(LogFilePath, destFileName);
                        }
                        catch (Exception ex)
                        {
                            ELogger.Error("拷贝log日志文件失败"+ex.Message);
                        }
                    }
                    ExportSuccess = ZipHelper.Zip(Program.DATA_FOLDER, zipFile);
                    //ExportSuccess = ZipHelper.ZipDirectoryExt(Program.DATA_FOLDER, zipFile);
                }
                catch (Exception ex)
                {
                    UploadMsg = ex.Message;
                    ELogger.Error(string.Format("压缩失败，异常信息:{0}", ex.Message));
                    ELogger.Error(string.Format("压缩失败，栈调用信息:{0}", ex.StackTrace));
                    return;
                }
            }
            if (ExportSuccess)
            {
                //DeleteDirectory(Program.DATA_FOLDER);
                if (Directory.Exists(Program.DATA_FOLDER)) 
                    Directory.Delete(Program.DATA_FOLDER,true);
            }
            else
            {
                UploadMsg = "打包失败，请重试";
                return;
            }
            try
            {
                //上传数据文件
                HttpHelper.NetCommunication netComm = new HttpHelper.NetCommunication();
                HttpHelper.UploadInfo upi =netComm.PostMicrotestData(zipFile, "");
                if (upi != null)
                    ELogger.Trace(string.Format("upi return code is {0}, msg is {1}", upi.ErrorCode, upi.ErrMsg));
                else
                    ELogger.Trace("upi is null");
                if(upi!=null&&upi.ErrorCode==0)
                {
                    UploadSuccess = true;
                    UploadMsg = string.Empty;
                }
                else
                {
                    UploadSuccess = false;
                    if (upi != null && upi.ErrMsg != null)
                        UploadMsg = upi.ErrMsg;
                    else
                        UploadMsg = "未知失败原因";
                }
            }
            catch (Exception ex)
            {
                ELogger.Error(string.Format("上传失败，异常信息:{0}", ex.Message));
                ELogger.Error(string.Format("上传失败，栈调用信息:{0}", ex.StackTrace));
                UploadSuccess = false;
                UploadMsg = ex.Message;
            }
            Thread.Sleep(1000);
            IsExporting = false;
        }

       /// <summary>
       /// 查看数据文件
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
        private void BtnBrowse_Click(object sender, EventArgs e)
        {
            //btnUpload.Enabled = false;
            if(ExportSuccess||UploadSuccess)
            {
                System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("Explorer.exe");
                psi.Arguments = "/e," + Program.DATA_ROOT;
                System.Diagnostics.Process.Start(psi);
            }
        }
        private void BtnExit_Click(object sender, EventArgs e)
        {
            if(DialogResult.OK==MessageBox.Show("是否退出？", "维思课堂", MessageBoxButtons.OKCancel,MessageBoxIcon.Question))
            {
                ELogger.Trace("退出考试");
                if (examStatus==ExamStatus.Exam_Examing)
                {
                    ELogger.Trace("考试进行中，执行结束考试操作！");
                    btnEnd_Click(this, null);
                }
                    
                this.Close();
                Application.Exit();
            }
            //focusBtn.Focus();
        }
        /// <summary>
        /// 更新连接状态提示信息
        /// </summary>
        private void UpdateCountStatus()
        {
            if(this.InvokeRequired)
            {
                Action ac = new Action(UpdateCountStatus);
                this.Invoke(ac);
            }
            else
            {
                this.labTotal.Text ="总人数："+ All.ToString();
                this.labCon.Text = "已连接："+Conn.ToString();
                this.labDis.Text = "未连接："+Disconn.ToString();
                ELogger.Trace(string.Format("总人数：{0}，已连接：{1}，未连接：{2}", All, Conn, Disconn));
            }
        }
        /// <summary>
        /// 更新笔连接列表的连接状态
        /// </summary>
        /// <param name="penSerial"></param>
        /// <param name="conn"></param>
        private void UpdatePenListStatus(string penSerial,bool conn=true)
        {
            if (this.InvokeRequired)
            {
                ELogger.Trace("UpdatePenListStatus Invoke CurrentThread ID is: " + Thread.CurrentThread.ManagedThreadId);

                Action<string,bool> ac = new Action<string,bool>(UpdatePenListStatus);
                this.Invoke(ac, new object[] { penSerial, conn });
            }
            else
            {
                ELogger.Trace("UpdatePenListStatus NoneInvoke CurrentThread ID is: " + Thread.CurrentThread.ManagedThreadId);

                //for (int i = 0; i < listView1.Items.Count; i++)
                //{
                //    if (listView1.Items[i].Text.Equals(penSerial))
                //    {
                //        if (conn)
                //            listView1.Items[i].ForeColor = Color.Green ;
                //        else
                //            listView1.Items[i].ForeColor = Color.Red;
                //        break;
                //    }
                //}
                foreach (var item in flpPenlist.Controls)
                {
                    PenItem pi = (PenItem)item;
                    if(pi.PenSerial.Equals(penSerial))
                    {
                        if (conn)
                            pi.ChangePenStatus(PenStatus.Normal);
                        else
                            pi.ChangePenStatus(PenStatus.DisConnected);
                        break;
                    }
                }

            }
        }
        /// <summary>
        /// 将标签与学生信息关联
        /// </summary>
        /// <param name="penserial"></param>
        /// <param name="pageSerial"></param>
        /// <param name="nx"></param>
        /// <param name="ny"></param>
        private void MapPenserialToStudent(string penserial,string pageSerial,int nx,int ny)
        {
            if(!studentListDic.ContainsKey(penserial))
            {
                string name=Program.MTInfo.GetStudentName(pageSerial, nx, ny);
                if (!string.IsNullOrEmpty(name))
                    studentListDic[penserial] = name;
            }
        }
        /// <summary>
        /// 添加笔迹小窗口
        /// </summary>
        /// <param name="penSerial"></param>
        private void AddCS2MainWindow(string penSerial)
        {
            if (this.InvokeRequired)
            {
                Action<string> action = new Action<string>(AddCS2MainWindow);
                this.Invoke(action, new object[] { penSerial });
            }
            else
            {
                DrawingWindow cs = new DrawingWindow(penSerial, Program.MTInfo.MicroTestPaperImage);
                statusWindows.Add(penSerial, cs);
                //pnlMain.Controls.Add(cs);
                int width = flpClient.Width;
                //cs.Width = 500;
                //cs.Height = (int)(1.0*500 * 297 / 420)+35;
                
                    
                if (windowHeight != 0)
                {
                    
                    cs.Height = windowHeight;
                    cs.Width = windowWidth;
                }
                else
                {
                    if (Program.MTInfo.MicroTestPaperImage.Count != 0)
                    {
                        foreach (var item in Program.MTInfo.MicroTestPaperImage)
                        {
                            if (item.Value.Width < item.Value.Height)
                            {
                                windowWidth = 210;
                                windowHeight = 297 + 35;

                            }
                            else
                            {
                                windowWidth = 420;
                                windowHeight = 297 + 35;
                            }
                            break;
                        }
                        cs.Width = windowWidth;
                        cs.Height = windowHeight;

                    }
                }
                int w = cs.Width;
                int l = width % w / 2;
                //flpClient.Padding = new Padding(20, 10, 20, 10);
                cs.Margin = new Padding(20, 10, 20, 10);
                flpClient.Controls.Add(cs);
                //cs.SetBackgroundImage(BackgroundImage);
                bool exsiting = false;
                //for (int i = 0; i < listView1.Items.Count; i++)
                //{
                //    if (listView1.Items[i].Text.Equals(penSerial))
                //    {
                //        listView1.Items[i].ForeColor = Color.Green;
                //        exsiting = true;
                //        break;
                //    }
                //}
                //if(!exsiting)
                //{
                //    ListViewItem lvi = new ListViewItem();
                //    lvi.Text = penSerial;
                //    lvi.ForeColor = Color.Green;
                //    listView1.Items.Add(lvi);
                //}
                foreach (var item in flpPenlist.Controls)
                {
                    PenItem pi = (PenItem)item;
                    if(pi.PenSerial.Equals(penSerial))
                    {
                        pi.ChangePenStatus(PenStatus.Normal);
                        exsiting = true;
                        break;
                    }
                }
                if(!exsiting)
                {
                    PenItem pi = new PenItem();
                    pi.PenSerial = penSerial;
                    pi.NormalImage = Resources.pen_ico_link;
                    pi.DisableImage = Resources.pen_ico_fail;
                    pi.DisconectedImage = Resources.pen_ico_fail;
                    pi.ClickPen += Pi_ClickPen;
                    flpPenlist.Controls.Add(pi);
                }
                
            }
            
        }

        private void Pi_ClickPen(object sender, ClickPenEventArgs args)
        {
            if (flpClient.Controls.Count == 0)
                return;
            if (currentPenItem != null)
                currentPenItem.Selected = false;
            currentPenItem = (sender as PenItem);
            currentPenItem.Selected = true;
            if(flpClient.Controls.Count==penItemList.Count)
            {
                foreach (var item in statusWindows)
                {
                    if (args.ItemName.Equals(item.Value.GetPenSerial()))
                    {
                        if (flpClient.VerticalScroll.Visible == false)
                            return;
                        int top = item.Value.Top;
                        int hpos = flpClient.HorizontalScroll.Value;
                        int pos = flpClient.VerticalScroll.Value + top;
                        flpClient.VerticalScroll.Value = pos;
                        flpClient.VerticalScroll.Value = pos;
                    }
                }
            }
            else
            {
                if (statusWindows.ContainsKey(args.ItemName)
                    &&!args.ItemName.Equals((flpClient.Controls[0] as DrawingWindow).GetPenSerial()))
                {
                    flpClient.SuspendLayout();
                   
                    flpClient.Controls.Add(statusWindows[args.ItemName]);
                    flpClient.Controls.RemoveAt(0);
                    flpClient.ResumeLayout();

                }

            }
            
        }

        private void UpdateStatusWindowName(string penSerial,string studentName)
        {
            if(this.InvokeRequired)
            {
                Action<string, string> ac = new Action<string, string>(UpdateStatusWindowName);
                this.Invoke(ac, new object[] { penSerial, studentName });
            }
            else
            {
                statusWindows[penSerial].SetName(studentListDic[penSerial]);

            }
        }
        private void UpdatePenListItemName(PenItem pi,string penName)
        {
            if (this.InvokeRequired)
            {
                Action<PenItem, string> ac = new Action<PenItem, string>(UpdatePenListItemName);
                this.Invoke(ac, new object[] { pi, penName });
            }
            else
            {
                pi.SetName(studentListDic[penName]);

            }
        }
        /// <summary>
        /// 抬笔
        /// </summary>
        /// <param name="time"></param>
        /// <param name="penSerial"></param>
        /// <param name="penType"></param>
        public void DigitalPen_PenUp(ulong time, string penSerial, int penType)
        {
            if (examStatus == ExamStatus.Exam_Stoped)
                return;
            if (penItemList.ContainsKey(penSerial))
            {
                UpdatePenSignInStatus(penSerial, PenStatus.Normal);
            }
            else if(studentListDic.ContainsKey(penSerial))
            {

                string oldPenSerial=ReplacePenItem(penSerial);
                ReplaceDrawingWindow(penSerial);
                if (studentListDic.ContainsKey(oldPenSerial))
                    studentListDic.Remove(oldPenSerial);
                Program.StudentInfo.UpdateCardPenSerial(oldPenSerial, penSerial);


                string folder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\WiseClass";
                if (!Directory.Exists(folder))
                    Directory.CreateDirectory(folder);
                folder = folder + "\\BindInfo";
                if (!Directory.Exists(folder))
                    Directory.CreateDirectory(folder);
                string bindData = string.Format("{0}\\{1}.cla", folder, Program.MTInfo.MicroTestRoomInfo);

                //string folder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\WiseClass";

                //if (!Directory.Exists(folder))
                //    Directory.CreateDirectory(folder);
                //string bindData = folder + "\\StudentList.cla";
                if (File.Exists(bindData))
                    File.Delete(bindData);
                bool ret = SerializeHelper.SerialData(bindData, Program.StudentInfo);

                ShowReplaceResult(studentListDic[penSerial], oldPenSerial, penSerial);
            }
            if (examStatus==ExamStatus.Exam_Examing)
            {
                saveStrokeAsync.PutPenUpEvent(penSerial);

                UpdatePenStatus(penSerial, 3);
                
            }
            
        }
        /// <summary>
        /// 落笔事件
        /// </summary>
        /// <param name="time"></param>
        /// <param name="penSerial"></param>
        /// <param name="penType"></param>
        public void DigitalPen_PenDown(ulong time, string penSerial, int penType)
        {
            if (examStatus == ExamStatus.Exam_Stoped)
                return;
            if (studentListDic.ContainsKey(penSerial))
            {
                UpdatePenSignInStatus(penSerial, PenStatus.Normal);
            }

            //IsPenDown = true;
            if (PenDownStatus.ContainsKey(penSerial))
                PenDownStatus[penSerial] = true;
            else
                PenDownStatus.Add(penSerial, true);
            if (examStatus == ExamStatus.Exam_Examing)
            {
                UpdatePenStatus(penSerial, 2);
                saveStrokeAsync.PutPenDownEvent(penSerial);
            }

        }
        /// <summary>
        /// 点阵笔坐标事件
        /// </summary>
        /// <param name="time"></param>
        /// <param name="penSerial"></param>
        /// <param name="penType"></param>
        /// <param name="pageSerial"></param>
        /// <param name="pageId"></param>
        /// <param name="cx"></param>
        /// <param name="cy"></param>
        /// <param name="force"></param>
        public void DigitalPen_PenCoordinate(ulong time, string penSerial, int penType, string pageSerial, ulong pageId, int cx, int cy, byte force)
        {
            if (examStatus == ExamStatus.Exam_Stoped)
                return;
            bool IsPaperPageSerial = Program.MTInfo.IsPaperPageSerial(pageSerial);
            bool IsStudentCard = Program.MTInfo.IsStudentCardPage(pageSerial);
            if (!IsPaperPageSerial/*Program.MTInfo.IsPaperPageSerial(pageSerial)*/ && !IsStudentCard/*Program.MTInfo.IsStudentCardPage(pageSerial)*/)
            {
                ELogger.Error(string.Format("{0} 非考试用纸，非学生标签！",pageSerial));
                return;
            }
            if(PenDownStatus.ContainsKey(penSerial)&&PenDownStatus[penSerial])
            {
                PenDownStatus[penSerial] = false;
                //改学生名字
                MapPenserialToStudent(penSerial, pageSerial, cx, cy);

            }
            //if (IsPenDown)
            //{
            //    IsPenDown = false;
            //    //改学生名字
            //    MapPenserialToStudent(penSerial, pageSerial, cx, cy);

            //}
            //statusWindows[penSerial].PenCoordinates(penSerial, pageSerial, cx,cy);
            if (examStatus == ExamStatus.Exam_Examing)
            {
                if (IsPaperPageSerial/*Program.MTInfo.IsPaperPageSerial(pageSerial)*/)

                    UpdateStroke(penSerial, pageSerial, cx, cy);
                    saveStrokeAsync.PutCoordinates(penSerial, pageSerial, cx, cy);
            }
        }
        /// <summary>
        /// 点阵笔连接
        /// </summary>
        /// <param name="time"></param>
        /// <param name="penSerial"></param>
        /// <param name="penType"></param>
        public void DigitalPen_PenConnected(ulong time, string penSerial, int penType)
        {
            ELogger.Trace(string.Format("{0} 建立连接", penSerial));

            if (examStatus == ExamStatus.Exam_Stoped)
                return;
            if (studentListDic.ContainsKey(penSerial))
            {
                UpdatePenSignInStatus(penSerial, PenStatus.Normal);
            }
            
        }
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="time"></param>
        /// <param name="penSerial"></param>
        /// <param name="penType"></param>
        public void DigitalPen_PenDisconnect(ulong time, string penSerial, int penType)
        {
            ELogger.Trace(string.Format("{0} 断开连接", penSerial));

            if (examStatus == ExamStatus.Exam_Stoped)
                return;
            if (studentListDic.ContainsKey(penSerial))
            {
                UpdatePenSignInStatus(penSerial, PenStatus.DisConnected);
            }
            
        }
        /// <summary>
        /// 更新DrawingWindow的书写状态
        /// </summary>
        /// <param name="penserial"></param>
        /// <param name="statusType"></param>
        private void UpdatePenStatus(string penserial,int statusType)
        {
            if (this.InvokeRequired)
            {
                Action<string, int> ac = new Action<string, int>(UpdatePenStatus);
                this.Invoke(ac, new object[] { penserial, statusType });

            }
            else
            {
                if (statusWindows.ContainsKey(penserial) == false)
                    return;
                switch (statusType)
                {
                    case 0://con
                        statusWindows[penserial].PenConnectedEvent(penserial);

                        break;
                    case 1://dis
                        statusWindows[penserial].PenDisconnectedEvent(penserial);

                        break;
                    case 2://down
                        statusWindows[penserial].OnPenDown(penserial);
                        break;
                    case 3://up
                        statusWindows[penserial].OnPenUp(penserial);

                        break;
                    default:
                        break;
                }
                //ELogger.Trace(string.Format("UpdatePenStatus None Invoke CurrentThread ID is: {0},pen serial {1}, status {2}" , Thread.CurrentThread.ManagedThreadId, penserial, statusType));


            }
        }
        /// <summary>
        /// 发送笔迹坐标到小窗口
        /// </summary>
        /// <param name="penserial"></param>
        /// <param name="pageSerial"></param>
        /// <param name="cx"></param>
        /// <param name="cy"></param>
        private void UpdateStroke(string penserial, string pageSerial,int cx,int cy)
        {
            if (this.InvokeRequired)
            {
                Action<string, string,int,int> ac = new Action<string, string, int, int>(UpdateStroke);
                this.Invoke(ac, new object[] { penserial, pageSerial, cx, cy });

            }
            else
            {
                if(statusWindows.ContainsKey(penserial))
                    statusWindows[penserial].PenCoordinates(penserial, pageSerial, cx, cy);
            }
        }
        
        /// <summary>
        /// 初始化控件
        /// </summary>
        private void InitControl()
        {
            this.tlpBase.Visible = false;
            {
                //labTitle.Left = (labTitle.Parent.Width - labTitle.Width) / 2;

                //开始考试按钮
                btnKs.Left = (btnKs.Parent.Width - btnKs.Width) / 2;
                btnKs.Top = 48;
                btnKs.Visible = true;

                //使用时间pnl
                pnlTimeConsum.Left = (pnlTimeConsum.Parent.Width - pnlTimeConsum.Width) / 2;
                pnlTimeConsum.Top = 20;
                labElaps.Left = (labElaps.Parent.Width - labElaps.Width) / 2;
                labElaps.Top = 0;
                //labYS.Left = labElaps.Left + (labElaps.Width - labYS.Width) / 2;
                //labYS.Top = labElaps.Bottom + 8;
                labYS.Visible = false;
                labTime.Left = labElaps.Left + (labElaps.Width - labTime.Width) / 2;
                labTime.Top = labElaps.Bottom + 8;
                //labTime.Visible = false;
                timerTime.Start();
                pnlTimeConsum.Visible = false;
                //结束按钮
                btnEnd.Left = pnlTimeConsum.Right;
                btnEnd.Top = 48;
                btnEnd.Visible = false;
                

                //开始时间   结束时间
                pnlStartInfo.Left = pnlTimeConsum.Left - pnlStartInfo.Width;
                pnlStartInfo.Top = 48;
                pnlEndInfo.Left = pnlTimeConsum.Right;
                pnlEndInfo.Top = pnlStartInfo.Top;
                pnlStartInfo.Visible = false;
                pnlEndInfo.Visible = false;

                //labTime.Left = (labTime.Parent.Width - labTime.Width - 10);
                //labTime.Top = 76;

                
                //列表
                flpPenlist.Width = flpPenlist.Parent.Width;
                flpPenlist.Height = flpPenlist.Parent.Height - 34 - 2;
                flpPenlist.Left = 0;
                flpPenlist.Top = 34;

                labBJ.Text = Program.MTInfo.MicroTestRoomInfo;

                labBJ.Top = labTime.Bottom;
                labBJ.Left = 10;

                labKS.Text = Program.MTInfo.MicroTestTitle;
                labKS.Top = labBJ.Top;
                labKS.Left = labTime.Parent.Width - 10 - labKS.Width;
                int spaceWidth = labTime.Left - 30 - btnEnd.Right;
                if (labKS.Width > spaceWidth)
                {
                    if (labKS.Width / 2 < spaceWidth)
                    {
                        string tmpStr = labKS.Text;
                        int mid = tmpStr.Length / 2;
                        string part1 = tmpStr.Substring(0, mid);
                        string part2 = tmpStr.Substring(mid, tmpStr.Length - mid);
                        labKS.Text = string.Format("{0}\n{1}", part1, part2);
                        labKS.Left = labTime.Parent.Width - 10 - labKS.Width;
                        labKS.Top = labTime.Bottom - labKS.Height;
                    }
                    else if (labKS.Width / 3 < spaceWidth)
                    {
                        string tmpStr = labKS.Text;
                        int mid = tmpStr.Length / 3;

                        string part1 = tmpStr.Substring(0, mid);
                        string part2 = tmpStr.Substring(mid, mid);
                        string part3 = tmpStr.Substring(mid + mid, tmpStr.Length - mid - mid);
                        labKS.Text = string.Format("{0}\n{1}\n{2}", part1, part2, part3);
                        labKS.Left = labTime.Parent.Width - 10 - labKS.Width;
                        labKS.Top = labTime.Bottom - labKS.Height;
                    }

                }
                btnExt.Enabled = false;
                btnBrowse.Enabled = false;
                btnUpload.Enabled = false;
                btnChoosePaper.Enabled = true;
            }
            this.tlpBase.Visible = true;
        }
        /// <summary>
        /// 加载测试图片
        /// </summary>
        private void LoadTestImage()
        {
            string pngFolder = Application.StartupPath + "\\png";
            DirectoryInfo di = new DirectoryInfo(pngFolder);
            FileInfo[] files=di.GetFiles();
            foreach (var item in files)
            {
                string fn = item.Name;
                fn = fn.Substring(0, fn.LastIndexOf('.'));
                string fullPath = item.FullName;
                Program.MTInfo.AddPaperPageImage(fn, Image.FromFile(fullPath));
            }
            
        }
       
        /// <summary>
        /// 更新考试时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timerTime_Tick(object sender, EventArgs e)
        {
            tickCount++;
            string tm= DateTime.Now.ToString("yyyy-MM-dd HH:mm");
            labTime.Text = tm;
            if(examStatus==ExamStatus.Exam_Examing)
            {
                TimeSpan ts = DateTime.Now - testStart;
                double allsec = ts.TotalSeconds;
                int min =(int)allsec / 60;
                int sec = (int)allsec % 60;
                string str=string.Format("{0:D2}'{1:D2}''", min, sec);
                labElaps.Text = str;

            }
        }
        
        /// <summary>
        /// 停止考试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnEnd_Click(object sender, EventArgs e)
        {
            ELogger.Trace("用户点击停止考试按钮！");
            if (examStatus==ExamStatus.Exam_Stoped)
            {
                ELogger.Trace("考试已经停止，此次点击无效");
                return;
            }
            
            examStatus = ExamStatus.Exam_Stoped;
            btnEnd.Visible = false;
            labEndTime.Text = DateTime.Now.ToString("HH:mm");
            //digitalPenAp.Stop();
            pnlEndInfo.Visible = true;
            ELogger.Trace("停止AP数据采集！");

            //digitalPenAp.Stop();
            try
            {
                string dataFile = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\WiseClass\\mt.dat";
                if (File.Exists(dataFile))
                {
                    File.Delete(dataFile);
                    ELogger.Trace("删除序列化文件");
                }
            }
            catch (Exception ex)
            {
                ELogger.Error(string.Format("删除序列化文件！{0}", ex.Message));
                ELogger.Error(string.Format("删除序列化文件！{0}", ex.StackTrace));

            }
            ELogger.Trace(string.Format("结束考试，结束时间{0}", labEndTime.Text));


            foreach (var item in flpPenlist.Controls)
            {
                PenItem pi = (PenItem)item;
                pi.ChangePenStatus(PenStatus.Disabled);
            }

            All = 0; Conn = 0; Disconn = 0;
            UpdateCountStatus();

            btnExt.Enabled = true;
            btnBrowse.Enabled = false;
            btnUpload.Enabled = true;

            IsStoped = true;
            ELogger.Trace("结束考试完毕");

        }
        /// <summary>
        /// 写入签到信息
        /// </summary>
        private void WriteStudentSignInData()
        {
            foreach (var item in Program.StudentInfo.BandList)
            {
                saveStrokeAsync.PutPenDownEvent(item.PenSerial);
                saveStrokeAsync.PutCoordinates(item.PenSerial, item.PageId, item.LeftBound + 100, item.TopBound + 100);
                saveStrokeAsync.PutPenUpEvent(item.PenSerial);
            }
        }
        /// <summary>
        /// 点击开始考试标签
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnKs_Click(object sender, EventArgs e)
        {

            ELogger.Trace("用户点击了开始考试按钮！");
            if(examStatus==ExamStatus.Exam_Sign)
            {
                ELogger.Trace("尚未选择试卷！");
                MessageBox.Show("尚未选择试卷！","智慧课堂",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                return;
            }
            
            if (examStatus==ExamStatus.Exam_Examing)
            {
                ELogger.Trace("考试进行中，此次点击无效！");
                return;
            }
            if (!ResumeMode)
                Program.MTInfo.IniExam();
            if (saveStrokeAsync == null)
                saveStrokeAsync = new SaveStrokeAsync();
            saveStrokeAsync.BeginSaving();
            WriteStudentSignInData();
            if (!ResumeMode)
            {
                try
                {
                    string dataFile = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\WiseClass\\mt.dat";
                    SerializeHelper.SerialData(dataFile, Program.MTInfo);
                    ELogger.Trace("序列化成功！");
                }
                catch (Exception ex)
                {
                    ELogger.Error(string.Format("数据序列化失败！{0}", ex.Message));
                    ELogger.Error(string.Format("数据序列化失败！{0}", ex.StackTrace));

                }
            }
            //btnKs.Enabled = false;

          
            btnKs.Visible = false;
            testStart = DateTime.Now;
            labStartTime.Text = testStart.ToString("HH:mm");
            pnlStartInfo.Visible = true;
            btnKs.Visible = false;
            pnlTimeConsum.Visible = true;

            examStatus = ExamStatus.Exam_Examing;
            btnEnd.Visible = true;

            btnChoosePaper.Enabled = false;
            ELogger.Trace(string.Format("开始考试，开始时间{0}", labStartTime.Text));
            ELogger.Trace("Main CurrentThread ID is: " + Thread.CurrentThread.ManagedThreadId);

        }

        
        /// <summary>
        /// 最小化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMin_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }
        /// <summary>
        /// 屏蔽空格和回车
        /// </summary>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Enter || keyData == Keys.Space)
                return false;
            return base.ProcessDialogKey(keyData);
        }
        /// <summary>
        /// 关闭考试界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            ELogger.Trace("用户点击了关闭按钮！");
            if (examStatus==ExamStatus.Exam_Examing)
            {
                ELogger.Trace("提示用户是否关闭考试客户端！");

                if (DialogResult.OK == MessageBox.Show("是否关闭考试客户端？", "提示", MessageBoxButtons.OKCancel))
                {
                    btnEnd_Click(this, null);
                    this.Update();
                    Thread.Sleep(2000);
                    ELogger.Trace("退出考试客户端，考试结束");
                    this.Close();
                    Application.Exit();
                }
                else
                    ELogger.Trace("用户选择不关闭客户端！");

            }
            else
            {
                ELogger.Trace("考试未进行，直接关闭客户端");

                this.Close();
                Application.Exit();
            }
        }
        /// <summary>
        /// 上传考试文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUpload_Click(object sender, EventArgs e)
        {
            ELogger.Trace("用户点击了上传按钮！");

            string zipFile = Program.DATA_ROOT + "\\" + Program.TEST_KEY + ".mt";


            IsExporting = true;
            FrmWait frmWait = new FrmWait(OperationMode.UploadMt,this);
            //this.Enabled = false;
            ELogger.Trace("开始上传数据...");
            backgroundWorker.RunWorkerAsync();
            frmWait.ShowDialog(this);

            frmWait.Close();
            frmWait.Dispose();
            if (ExportSuccess&&UploadSuccess)
            {
                ELogger.Trace(string.Format("数据上传{0}", ExportSuccess ? "成功" : "失败"));
                MessageBox.Show("考试文件上传成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            
            else
            {
                //MessageBox.Show(string.Format("导出数据失败，请重试或手动拷贝{0}下的数据", Application.StartupPath + "\\data"));
                MessageBox.Show(string.Format("上传失败，请稍后再试或联系系统管理员。\r\n失败原因:{0}",UploadMsg),"上传失败",MessageBoxButtons.OK,MessageBoxIcon.Error);
                ELogger.Trace(string.Format("数据上传{0}, msg:{1}", UploadSuccess ? "成功" : "失败",UploadMsg));
            }
            if(ExportSuccess)
            {
                btnBrowse.Enabled = true;
            }
            if(UploadSuccess)
            {
                btnUpload.Enabled = false;
            }
        }
        private void DisableButton(object btn)
        {
            if(this.InvokeRequired)
            {
                Action<object> ac = new Action<object>(DisableButton);
                this.Invoke(ac, new object[] { btn });
            }
            else
            {
                (btn as ImageButton).NormalImage = Properties.Resources.btn_upload_disabled;
                (btn as ImageButton).Enabled = false;
            }
        }
        
        /// <summary>
        /// 放大界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnZoomIn_Click(object sender, EventArgs e)
        {
            if (flpClient.Controls.Count == 0)
                return;
            int controlCount = flpClient.Controls.Count;
            for (int i = controlCount-1; i>0; i--)
            {
                flpClient.Controls.RemoveAt(i);
            }



            foreach (var item in statusWindows)
            {
                int width = item.Value.Width;
                int height = item.Value.Height;
                int index = -1;
                for (int i = 0; i < zoomValues.Count; i++)
                {
                    if(zoomValues[i].X==width&&zoomValues[i].Y==height)
                    {
                        index = i;
                        break;
                    }
                }
                if (index == zoomValues.Count - 1||index==-1)
                    break;
                index += 1;
                ZoomSize zs = zoomValues[index];
                
                width = zs.X;
                height = zs.Y;
                item.Value.SuspendLayout();
                item.Value.Width = width;
                item.Value.Height = height;
                //item.Value.SetWindowsSize(width, height);
                
                int leftMargin = 0;
                if (index == 1)
                    leftMargin = (flpClient.Width - width) / 2-10;
                else if (index == 2)
                    leftMargin = 10;
                item.Value.Margin = new Padding(leftMargin, 10, leftMargin, 10);
                item.Value.ResumeLayout();
                windowWidth = width;
                windowHeight = height;
            }
        }
        /// <summary>
        /// 缩小界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnZoomOut_Click(object sender, EventArgs e)
        {

            if (flpClient.Controls.Count == 0)
                return;
            int controlCount = flpClient.Controls.Count;

            int width = flpClient.Controls[0].Width;
            int height = flpClient.Controls[0].Height;
            int index = -1;
            for (int i = 0; i < zoomValues.Count; i++)
            {
                if (zoomValues[i].X == width && zoomValues[i].Y == height)
                {
                    index = i;
                    break;
                }
            }
            if (index == 0 || index == -1)
                return;
            index -= 1;
            flpClient.SuspendLayout();
            if (index == 0 && statusWindows.Count > 1)
                flpClient.Controls.Clear();
            foreach (var item in statusWindows)
            {
                
                
                ZoomSize zs = zoomValues[index];
                width = zs.X;
                height = zs.Y;
                //item.Value.SuspendLayout();
                item.Value.Width = width;
                item.Value.Height = height;
                //item.Value.SetWindowsSize(width, height,false);
                int leftMargin = 0;
                if (index == 0)
                    leftMargin = 20;
                else if (index == 1)
                    leftMargin = (flpClient.Width - width) / 2-10;
                else if (index == 2)
                    leftMargin = 10;
                item.Value.Margin = new Padding(leftMargin, 10, leftMargin, 10);
                //item.Value.ResumeLayout();
                if(index == 0 && statusWindows.Count > 1)
                {
                    item.Value.SetLabelVisable(false);
                    //item.Value.Visible = false;
                    flpClient.Controls.Add(item.Value);

                }

                windowWidth = width;
                windowHeight = height;
            }
            flpClient.ResumeLayout();
            foreach (var item in flpClient.Controls)
            {
                (item as DrawingWindow).SetLabelVisable(true);
            }
            
            
            //flpClient.PerformLayout();
        }
        /// <summary>
        /// 选择考试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnChoosePaper_Click(object sender, EventArgs e)
        {
            if (examStatus != ExamStatus.Exam_Sign && examStatus != ExamStatus.Exam_LoadedPaper)
                return;
            ELogger.Trace("选择考试试卷");
            FrmChooseExam frmChooseExam = new FrmChooseExam();
            frmChooseExam.SetGradeInfo(Program.MTInfo.MicroTestGradeID, "");
            frmChooseExam.SetClassInfo(Program.MTInfo.MicroTestClassID, "");
            frmChooseExam.SetUserInfo(Program.MTInfo.MicroTestUserName);
            if (DialogResult.OK == frmChooseExam.ShowDialog())
            {
                //清空原有的窗口
                statusWindows.Clear();
                flpClient.Controls.Clear();
                windowWidth = 0;
                windowHeight = 0;
                //加载新的窗口
                LoadDrawingWindws();
                labKS.Text = "【"+Program.MTInfo.MicroTestTitle+"】";
                labKS.Top = labBJ.Top;
                labKS.Left = labBJ.Right;// labTime.Parent.Width - 10 - labKS.Width;
                if (labKS.Right > pnlStartInfo.Left)
                {
                    labKS.Width = pnlStartInfo.Left - labKS.Left - 20;
                }
                
                examStatus = ExamStatus.Exam_LoadedPaper;
                ELogger.Trace(string.Format("加载试卷{0}完毕", Program.MTInfo.MicroTestTitle));
            }

        }
        
        private void btnBackground_Click(object sender, EventArgs e)
        {
            if (examStatus == ExamStatus.Exam_Sign || examStatus == ExamStatus.Exam_Stoped)
                return;
            ShowBackground = !ShowBackground;
            foreach (var item in statusWindows)
            {
                item.Value.SetBackgroundVisible(ShowBackground);
            }
            if(!ShowBackground)
            {
                btnBackground.NormalImage = Resources.oper_btn_showbg;
                btnBackground.HoverImage = Resources.oper_btn_showbg_hover;
                btnBackground.DownImage = Resources.oper_btn_showbg_active;
                btnBackground.DisableImage = Resources.oper_btn_showbg_disabled;
            }
            else
            {
                btnBackground.NormalImage = Resources.oper_btn_hidebg;
                btnBackground.HoverImage = Resources.oper_btn_hidebg_hover;
                btnBackground.DownImage = Resources.oper_btn_hidebg_active;
                btnBackground.DisableImage = Resources.oper_btn_hidebg_disabled;
            }
        }
        /// <summary>
        /// 考试名称tooltip
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labKS_MouseEnter(object sender, EventArgs e)
        {
            toolTipExam.IsBalloon = false;
            toolTipExam.SetToolTip(this.labKS, labKS.Text);
        }

        private void btnGoToClass_Click(object sender, EventArgs e)
        {
            if(examStatus==ExamStatus.Exam_Examing)
            {
                MessageBox.Show("考试进行中无法切换到上课模式！", "维思课堂", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (DialogResult.OK == MessageBox.Show("是否切换到上课模式？", "维思课堂", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
            {
                ELogger.Trace("用户切换到上课模式");
                statusWindows.Clear();
                flpClient.Controls.Clear();
                Program.CurrentClassInfo.ClearSymPageImage();
                penItemList.Clear();
                flpPenlist.Controls.Clear();
                GC.Collect();
                this.Hide();
                FrmSwhich.SwhichFrm.SwichToScene(SceneType.Scene_Class);
            }
        }

        public void ZoomOutDrawingWindow()
        {
            foreach (var item in statusWindows)
            {
                int width = (int)(item.Value.Width / 1.2);
                int height = (int)((item.Value.Height - 35) / 1.2) + 35;

                ZoomSize zs = GetPropeZoomSize(width, height);
                if (zs.X == -1)
                {
                    return;
                }
                width = zs.X;
                height = zs.Y;
                item.Value.SuspendLayout();
                item.Value.Width = width;
                item.Value.Height = height;

                int lineCount = flpClient.Width / (width + 40);
                int leftMargin = (flpClient.Width - lineCount * (width + 40)) / lineCount / 2;
                if(leftMargin<20)
                    leftMargin = (flpClient.Width - (lineCount-1) * (width + 40)) / (lineCount - 1) / 2;
                item.Value.Margin = new Padding(leftMargin, 10, leftMargin, 10);
                item.Value.ResumeLayout();
                windowWidth = width;
                windowHeight = height;
            }
        }
        private ZoomSize GetPropeZoomSize(int x,int y)
        {
            for (int i = 0; i < zoomValues.Count; i++)
            {
                if (Math.Abs(zoomValues[i].X - x) < 15)
                    return zoomValues[i];
            }
            ZoomSize zs = new ZoomSize(-1, -1);
            return zs;
        }
        public void SaveCurrentDrawingImageWhenExcpetion()
        {
            foreach (var item in statusWindows)
            {
                string key = item.Key;
                DrawingWindow dw = item.Value;
                dw.SaveDrawingImage();
            }
        }
    }
    public class ZoomSize
    {
        public int X;
        public int Y;
        public ZoomSize(int x,int y)
        {
            X = x;
            Y = y;
        }
    }
    public enum ExamStatus
    {
        Exam_Sign,
        Exam_LoadedPaper,
        Exam_Examing,
        Exam_Stoped
    }

}
